from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings
import hashlib
import time
import random
import string
import requests
import xml.etree.ElementTree as ET
from .models import WechatUserInfo, WechatPayment, AppResource
import logging
from django.http import JsonResponse

logger = logging.getLogger(__name__)

def dict_to_xml(dict_data):
    """将字典转换为XML格式"""
    xml = ["<xml>"]
    for k, v in dict_data.items():
        xml.append(f"<{k}>{v}</{k}>")
    xml.append("</xml>")
    return ''.join(xml)

def xml_to_dict(xml_str):
    """将XML转换为字典"""
    try:
        xml = ET.fromstring(xml_str)
        return {child.tag: child.text for child in xml}
    except ET.ParseError:
        return {}

def generate_nonce_str(length=32):
    """生成随机字符串"""
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

def generate_sign(params, key=None):
    """生成签名"""
    key = key or settings.WECHAT_PAY_CONFIG['mch_key']
    sorted_params = sorted(params.items())
    stringA = '&'.join([f"{k}={v}" for k, v in sorted_params if v and k != 'sign'])
    stringSignTemp = f"{stringA}&key={key}"
    return hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
# 微信支付
class WechatPay(APIView):
    def get(self, request):
        """获取用户openid"""
        logger.info("收到获取 openid 请求")
        code = request.query_params.get('code')
        logger.info(f"请求参数 code: {code}")
        
        if not code:
            logger.error("缺少 code 参数")
            return Response({'error': '缺少code参数'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 调用微信登录API
        url = f"https://api.weixin.qq.com/sns/jscode2session"
        params = {
            'appid': settings.WECHAT_PAY_CONFIG['appid'],
            'secret': settings.WECHAT_PAY_CONFIG['appsecret'],
            'js_code': code,
            'grant_type': 'authorization_code'
        }
        logger.info(f"请求微信API: {url}, 参数: {params}")
        
        response = requests.get(url, params=params)
        data = response.json()
        logger.info(f"微信API响应: {data}")
        
        if 'openid' not in data:
            logger.error(f"获取openid失败: {data}")
            return Response({'error': '获取openid失败'}, status=status.HTTP_400_BAD_REQUEST)
        
        openid = data['openid']
        # 保存用户信息
        user, created = WechatUserInfo.objects.get_or_create(openid=openid)
        logger.info(f"用户信息{'创建' if created else '获取'}成功: {openid}")
        
        return Response({'openid': openid}, status=status.HTTP_200_OK)

    def post(self, request):
        """统一下单"""
        openid = request.data.get('openid')
        total_fee = request.data.get('total_fee')
        ip = request.META.get('REMOTE_ADDR')
        
        if not all([openid, total_fee]):
            return Response({'error': '缺少必要参数'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 生成商户订单号
        out_trade_no = f"{int(time.time())}{random.randint(1000, 9999)}"
        
        # 统一下单参数
        params = {
            'appid': settings.WECHAT_PAY_CONFIG['appid'],
            'mch_id': settings.WECHAT_PAY_CONFIG['mch_id'],
            'nonce_str': generate_nonce_str(),
            'body': '商品描述',
            'out_trade_no': out_trade_no,
            'total_fee': int(float(total_fee) * 100),
            'spbill_create_ip': ip,
            'notify_url': settings.WECHAT_PAY_CONFIG['notify_url'],
            'trade_type': settings.WECHAT_PAY_CONFIG['trade_type'],
            'openid': openid
        }
        
        # 生成签名
        params['sign'] = generate_sign(params)
        
        # 调用统一下单API
        response = requests.post(
            'https://api.mch.weixin.qq.com/pay/unifiedorder',
            data=dict_to_xml(params),
            headers={'Content-Type': 'application/xml'}
        )
        
        # 处理响应
        result = xml_to_dict(response.content)
        if result.get('return_code') == 'SUCCESS' and result.get('result_code') == 'SUCCESS':
            # 创建支付记录
            WechatPayment.objects.create(
                user=WechatUserInfo.objects.get(openid=openid),
                out_trade_no=out_trade_no,
                total_fee=total_fee,
                ip_address=ip,
                status='pending'
            )
            
            # 返回支付参数
            pay_params = {
                'timeStamp': str(int(time.time())),
                'nonceStr': generate_nonce_str(),
                'package': f"prepay_id={result['prepay_id']}",
                'signType': settings.WECHAT_PAY_CONFIG['sign_type']
            }
            pay_params['paySign'] = generate_sign(pay_params)
            
            return Response(pay_params, status=status.HTTP_200_OK)
        else:
            return Response({'error': result.get('return_msg', '支付失败')}, status=status.HTTP_400_BAD_REQUEST)

# 支付结果通知
class WechatNotify(APIView):
    """支付结果通知"""
    def post(self, request):
        # 解析通知数据
        data = xml_to_dict(request.body)
        
        # 验证签名
        sign = data.pop('sign')
        if generate_sign(data) != sign:
            return Response({'return_code': 'FAIL', 'return_msg': '签名验证失败'})
        
        # 更新支付状态
        try:
            payment = WechatPayment.objects.get(out_trade_no=data['out_trade_no'])
            if data['return_code'] == 'SUCCESS':
                payment.status = 'success'
                payment.transaction_id = data['transaction_id']
            else:
                payment.status = 'failed'
            payment.save()
            
            return Response({'return_code': 'SUCCESS', 'return_msg': 'OK'})
        except WechatPayment.DoesNotExist:
            return Response({'return_code': 'FAIL', 'return_msg': '订单不存在'})

# 查询订单状态
class WechatQuery(APIView):
    """查询订单状态"""
    def post(self, request):
        out_trade_no = request.data.get('out_trade_no')
        if not out_trade_no:
            return Response({'error': '缺少订单号'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 查询参数
        params = {
            'appid': settings.WECHAT_PAY_CONFIG['appid'],
            'mch_id': settings.WECHAT_PAY_CONFIG['mch_id'],
            'nonce_str': generate_nonce_str(),
            'out_trade_no': out_trade_no
        }
        params['sign'] = generate_sign(params)
        
        # 调用查询API
        response = requests.post(
            'https://api.mch.weixin.qq.com/pay/orderquery',
            data=dict_to_xml(params),
            headers={'Content-Type': 'application/xml'}
        )
        
        # 处理响应
        result = xml_to_dict(response.content)
        if result.get('return_code') == 'SUCCESS':
            return Response(result, status=status.HTTP_200_OK)
        else:
            return Response({'error': result.get('return_msg', '查询失败')}, status=status.HTTP_400_BAD_REQUEST)

def get_resources(request):
    """获取所有启用的资源"""
    resources = AppResource.objects.filter(is_active=True).values('key', 'value', 'type')
    return JsonResponse(list(resources), safe=False)
